#include <arm_neon.h>

namespace NTEngine {
namespace Math {

// 組み込み関数でmul add
void maddVec4( const float* in, float t, float* out ) {
#if 1
	float32_t ta[4] = { t, t, t, t };
	float32x4_t a = vld1q_f32( &ta[0] );
	float32x4_t b = vld1q_f32( reinterpret_cast< const float32_t* >( in ) );
	float32x4_t c = vld1q_f32( reinterpret_cast< const float32_t* >( out ) );
	float32x4_t r = vmlaq_f32( a, b, c );
	vst1q_f32( reinterpret_cast< float32_t* >( out ), r );
#else
	for ( int i = 0; i < 4; ++i ) {
		out[ i ] += in[ i ] * t;
	}
#endif
}

// インラインアセンブラで行列の積
void mulMat( const float* m0, const float* m1, float* dest ) {
	__asm__ __volatile__ (
	"vld1.32 {d16-d19}, [%1]!\n"
	"vld1.32 {d20-d23}, [%1]!\n"
	"vld1.32 {d0-d3}, [%2]!\n"
	"vld1.32 {d4-d7}, [%2]!\n"
	"vmul.f32 q12, q8, d0[0]\n"
	"vmul.f32 q13, q8, d2[0]\n"
	"vmul.f32 q14, q8, d4[0]\n"
	"vmul.f32 q15, q8, d6[0]\n"
	"vmla.f32 q12, q9, d0[1]\n"
	"vmla.f32 q13, q9, d2[1]\n"
	"vmla.f32 q14, q9, d4[1]\n"
	"vmla.f32 q15, q9, d6[1]\n"
	"vmla.f32 q12, q10, d1[0]\n"
	"vmla.f32 q13, q10, d3[0]\n"
	"vmla.f32 q14, q10, d5[0]\n"
	"vmla.f32 q15, q10, d7[0]\n"
	"vmla.f32 q12, q11, d1[1]\n"
	"vmla.f32 q13, q11, d3[1]\n"
	"vmla.f32 q14, q11, d5[1]\n"
	"vmla.f32 q15, q11, d7[1]\n"
	"vst1.32 {d24-d27}, [%0]!\n"
	"vst1.32 {d28-d31}, [%0]!\n"
	: "=r"(dest)
	: "r"(m0), "r"(m1)
	: "q0","q1","q2","q3", "q8","q9","q10","q11", "q12","q13","q14","q15"
	);
}

} // namespace Math
} // namespace NTEngine
